<?php

namespace App\Admin\Controllers;

use App\Admin\Extensions\Tools\QuestionTools;
use App\Admin\Repositories\Question as QuestionRepository;
use App\Models\Category;
use App\Models\Question;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Show;
use Dcat\EasyExcel\Excel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class QuestionController extends AdminController
{
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        // 题目类型
        $types = [
            Question::TYPE_OF_RADIO => '选择题',
            Question::TYPE_OF_CHECKBOX => '多选题',
            Question::TYPE_OF_TF => '判断题',
        ];

        return Grid::make(QuestionRepository::with(['category']), function (Grid $grid) use ($types) {
            $grid->column('id')->sortable();
            $grid->column('question')->width(300);
            $grid->column('type')->using($types)->label(['blue', 'green', 'orange']);
            $grid->column('category.name', trans('question.fields.category'))->width(150);
            $grid->column('answer')->width(50)->display(function () {
                /** @var Question $this */
                return $this->getOriginal('answer');
            });
            $grid->column('options', '选项')->width(400)->display(function () {
                /** @var Question $this */
                if ($this->type === Question::TYPE_OF_TF) {
                    return '<ul><li>1. 正确</li><li>2. 错误</li></ul>';
                }

                return <<<HTML
    <ul>
        <li>1. $this->option_1</li>
        <li>2. $this->option_2</li>
        <li>3. $this->option_3</li>
        <li>4. $this->option_4</li>
    </ul>
HTML;
            });
            $grid->column('created_at');
            $grid->column('updated_at')->sortable();

            $grid->filter(function (Grid\Filter $filter) use ($types) {
                $filter->equal('id');
                $filter->like('question');
                $filter->equal('type')->select($types);
                $filter->equal('category_id')->select(Category::getFromCache()->pluck('name', 'id'));
            });

            // 工具栏
            $grid->tools(function (Grid\Tools $tools) {
                $tools->append(new QuestionTools());
            });
        });
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     *
     * @return Show
     */
    protected function detail($id)
    {
        $model = Question::with('category');

        return Show::make($id, $model, function (Show $show) {
            $show->field('id');
            $show->field('question');
            $show->field('category.name', '题库分类');
            $show->field('type')->as(function () {
                /** @var Question $this */
                return $this->type_name;
            });
            $show->field('answer')->as(function () {
                /** @var Question $this */
                return $this->getOriginal('answer');
            })->prepend('选项 ');

            if ($show->model()->type === Question::TYPE_OF_TF) {
                $show->field('option_1')->as(function () { return '正确'; });
                $show->field('option_2')->as(function () { return '错误'; });
            } else {
                $show->field('option_1');
                $show->field('option_2');
                $show->field('option_3');
                $show->field('option_4');
            }

            $show->field('created_at');
            $show->field('updated_at');
        });
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        return Form::make(new QuestionRepository(), function (Form $form) {
            $options = [
                1 => '选项 1',
                2 => '选项 2',
                3 => '选项 3',
                4 => '选项 4',
            ];

            $form->display('id');
            $form->textarea('question')->required();
            $form->select('category_id')->options(Category::getFromCache()->pluck('name', 'id'))->required();
            $form->radio('type')
                ->when(Question::TYPE_OF_RADIO, function (Form $form) use ($options) {
                    if ($form->isEditing()) {
                        $answer = (int) $form->model()->getOriginal('answer');
                    }
                    $form->radio('answer_radio')->options($options)->default($answer ?? 1, true)->required()->rules('required_if:type,0');
                })
                // ->when(Question::TYPE_OF_CHECKBOX, function (Form $form) use ($options) {
                //     if ($form->isEditing()) {
                //         $answer = explode(',', $form->model()->getOriginal('answer'));
                //     }
                //     $form->checkbox('answer_checkbox')->options($options)->default($answer ?? [1, 2], true)->required()->rules(function (Form $form) {
                //         return 'required_if:type,1' . ($form->input('type') == 1 ? '|min:2|max:4' : '');
                //     });
                // })
                ->when(Question::TYPE_OF_TF, function (Form $form) {
                    if ($form->isEditing()) {
                        $answer = $form->model()->getOriginal('answer') == 1 ? 1 : 2;
                    }
                    $form->radio('answer_tf')->options([1 => '正确', 2 => '错误'])->default($answer ?? 1, true)->required()->rules('required_if:type,2');
                })
                ->options([Question::TYPE_OF_RADIO => '选择题', Question::TYPE_OF_TF => '判断题'])
                ->default(0)
                ->required()
                ->help('判断题可不填下列选项！');

            $form->hidden('answer');
            $form->text('option_1')->rules('required_if:type,0,1');
            $form->text('option_2')->rules('required_if:type,0,1');
            $form->text('option_3');
            $form->text('option_4');

            $form->display('created_at');
            $form->display('updated_at');
        })->saving(function (Form $form) {
            switch ($form->input('type')) {
                case Question::TYPE_OF_CHECKBOX:
                    $form->input('answer', implode(',', array_filter((array) $form->input('answer_checkbox'))));
                    break;
                case Question::TYPE_OF_TF:
                    $form->input('answer', $form->input('answer_tf') == 1 ? 1 : 2);
                    $form->input('option_1', '正确');
                    $form->input('option_2', '错误');
                    $form->input('option_3', '');
                    $form->input('option_4', '');
                    break;
                default:
                    $form->input('answer', (int) $form->input('answer_radio'));

            }

            $form->deleteInput('answer_radio');
            $form->deleteInput('answer_checkbox');
            $form->deleteInput('answer_tf');
        })->saved(function (Form $form) {
            Cache::store()->tags('questions')->forget($form->getKey());
            // 统计各分类题目数
            Category::refreshQuestionCount();
        })->deleted(function (Form $form) {
            Cache::store()->tags('questions')->forget($form->getKey());
            // 统计各分类题目数
            Category::refreshQuestionCount();
        });
    }

    /**
     * 导入题库
     *
     * @param Request $request
     * @return \Dcat\Admin\Http\JsonResponse
     */
    public function import(Request $request)
    {
        set_time_limit(0);

        // 直接读取前端上传的文件
        try {
            $questions = Excel::import($request->file('_file_'))->first()->toArray();
        } catch (\Exception $e) {
            return \Admin::json()->error('无法读取文件！');
        }

        // 题库分类
        $categories = Category::query()->pluck('name', 'id');

        // 题目类型
        $types = [
            '选择题' => Question::TYPE_OF_RADIO,
            '多选题' => Question::TYPE_OF_CHECKBOX,
            '判断题' => Question::TYPE_OF_TF,
        ];

        $createdAt = now();

        $questions = collect($questions)->map(function ($question) use (&$categories, $types, $createdAt) {
            $categoryId = $categories->search($question['题库分类']);

            // 题库分类不存在时创建
            if (! $categoryId) {
                $categoryId = Category::query()->insertGetId([
                    'name' => $question['题库分类'],
                    'order' => Category::query()->max('order') + 1,
                    'created_at' => now(),
                ]);
                $categories = $categories->put($categoryId, $question['题库分类']);
            }

            $data = [
                'question' => $question['题目'],
                'type' => $types[$question['类型']] ?? Question::TYPE_OF_RADIO,
                'category_id' => $categoryId,
                'answer' => $question['正确答案'],
                'created_at' => $createdAt,
            ];

            if ($data['type'] == Question::TYPE_OF_TF) {
                $data['option_1'] = '正确';
                $data['option_2'] = '错误';
                $data['option_3'] = '';
                $data['option_4'] = '';
            } else {
                $data['option_1'] = $question['答案选项1'];
                $data['option_2'] = $question['答案选项2'];
                $data['option_3'] = $question['答案选项3'];
                $data['option_4'] = $question['答案选项4'];
            }

            return $data;
        })->toArray();

        try {
            Question::query()->insertOrIgnore($questions);

            // 统计各分类题目数
            Category::refreshQuestionCount();

            return \Admin::json()->success('导入成功！');
        } catch (\Exception $e) {
            return \Admin::json()->error('导入失败！');
        }
    }
}
